package com.whu.MenuHub.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whu.MenuHub.dao.FoodCommentDao;
import com.whu.MenuHub.dao.FoodDao;
import com.whu.MenuHub.dao.OrderDao;
import com.whu.MenuHub.domain.*;
import com.whu.MenuHub.exception.MenuHubException;
import com.whu.MenuHub.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class OrderServiceImpl  extends ServiceImpl<OrderDao, Order> implements OrderService {

    @Autowired
    OrderDao orderDao;

    @Autowired
    FoodCommentDao foodJudgementDao;
    @Autowired
    FoodDao foodDao;
    //根据订单id获取订单信息
    @Cacheable(cacheNames = "order",key = "#id",condition = "#id!=null")
    @Override
    public OrderDTO getOrderDetailByOrderID(Integer id){
        return orderDao.getOrderDetailByOderID(id);
    }

    //根据条件获取订单信息,分页返回
    @Override
    public IPage<Order> getOrders(Map<String, Object> condition, Integer pageNum, Integer pageSize){
        IPage page = new Page(pageNum, pageSize);
        QueryWrapper<Order> qw = new QueryWrapper<>();
        qw.eq(condition.containsKey("userID"),"userID", condition.get("userID"));
        qw.like(condition.containsKey("comment"),"comment", condition.get("comment"));

        if(condition.containsKey("orderField")){
            String orderField=condition.get("orderField").toString();
            //当排序的类型不为空，且为降序的时候，按照降序排列
            if(condition.containsKey("orderType")&&condition.get("orderType").equals("ASC")){
                qw.orderByAsc(orderField);
            }
            //当排序的类型为空，或指明升序，则按升序排列
            else{
                qw.orderByDesc(orderField);
            }
        }else{
            qw.orderByDesc("orderTime");
        }
        if(condition.containsKey("state")){
            String state=condition.get("state").toString();
            System.out.println(state);
            switch(state){
                case "orderPlaced":
                    qw.isNull("orderRecTime").eq("hasRejected", false);
                    break;
                case "orderAccepted":
                    qw.isNotNull("orderRecTime").isNull("orderFinishTime");
                    break;
                case "orderFinished":
                    qw.isNotNull("orderFinishTime");
                    break;
                case "orderRejected":
                    qw.eq("hasRejected", true);
                    break;
            }
        }
        IPage<Order>records=orderDao.findOrders(page, qw);
        //整体查询订单的时候，显示的照片是第一个食物的照片
        for(Order order:records.getRecords()){
            FoodComment comment=foodJudgementDao.findOneFoodCommentByOrderID(order.getId());
            Food food=foodDao.selectById(comment.getFoodID());
            order.setPhoto(food.getPhoto());
        }
        return records;
    }

    //修改一条订单信息
    @Transactional(rollbackFor = MenuHubException.class)
    @Override
    @CacheEvict(cacheNames = "order",key = "#order.id")
    public void updateOrderByID(Order order) throws MenuHubException{
        try{
            //修改信息
            orderDao.updateById(order);
        }catch (Exception e){
            throw new MenuHubException(MenuHubException.ErrorType.UPDATE_ERROR,"修改订单信息失败");
        }
    }

    //删除一条订单信息
    @Override
    @Transactional(rollbackFor = MenuHubException.class)
    @CacheEvict(cacheNames = "order",key = "#id")
    public void deleteOrderbyOrderID(Integer id) throws MenuHubException {
        try{
            List<FoodCommentDTO>judgements=foodJudgementDao.findfoodjudgeByOrderID(id);
            if(judgements!=null){
                //先删除食品评价表中的信息
                for(FoodComment judgement:judgements){
                    foodJudgementDao.deleteById(judgement.getId());
                }
            }
            orderDao.deleteById(id);
        }catch (Exception e){
            throw new MenuHubException(MenuHubException.ErrorType.INSERT_ERROR,"删除订单信息失败");
        }
    }

    //增加一条订单信息
    @Override
    @Transactional(rollbackFor = MenuHubException.class)
    @Cacheable(cacheNames = "order",key = "#orderDTO.id",condition = "#orderDTO.id!=null")
    public Order insertOrder(OrderDTO orderDTO) throws MenuHubException {
        System.out.println("service");
        try{
            Order order=(Order)orderDTO;
            System.out.println(order.toString());
            //强制转换后插入
            orderDao.insert(order);
            Integer orderID=order.getId();
            List<FoodCommentDTO>judgementList=orderDTO.getFoodJudgementList();
            //循环插入订单的菜品
            for(FoodComment judgement:judgementList){
                //更新订单插入表格后的id值
                judgement.setOrderID(orderID);
                foodJudgementDao.insert(judgement);
                //获取食物的信息，更新食物的总销量
                Food food=foodDao.selectById(judgement.getFoodID());
                food.setSaleNumber(food.getSaleNumber()+judgement.getFoodNumber());
            }
            return order;
        }catch (Exception e){
            throw new MenuHubException(MenuHubException.ErrorType.INSERT_ERROR,"添加订单信息失败");
        }
    }

    //更新订单的评价信息,同时需要修改食品表中的评价信息和点赞信息
    @Override
    @CacheEvict(cacheNames = "order",key = "#orderDTO.id")
    @Transactional(rollbackFor = MenuHubException.class)
    public void updateOrderComment(OrderDTO orderDTO)throws MenuHubException{
        try{
            List<FoodCommentDTO>judgementList=orderDTO.getFoodJudgementList();
            //循环更新订单菜品的评价信息
            for(FoodComment judgement:judgementList){
                foodJudgementDao.updateById(judgement);
                //获取食品的id
                Integer foodID=judgement.getFoodID();
                //获取到食品
                Food food=foodDao.selectById(foodID);
                //获取到食品评价表中食品的项数
                int commentNum=foodJudgementDao.findOrderNumberByFoodID(foodID);
                //计算之前的总评分+现在的评分，更新食品的平均分
                float score=commentNum*food.getFoodScore()+judgement.getFoodscore();
                //限制float的精度
                DecimalFormat df = new DecimalFormat("##.##");
                float newsocre=score/(commentNum+1);
                food.setFoodScore(Float.parseFloat(df.format(newsocre)));
                //更新食品的点赞量
                food.setFoodStar(food.getFoodStar()+judgement.getStar());
                //把商品更新到表格中
                foodDao.updateById(food);
            }
            //更新订单表中的信息
            Order order=(Order)orderDTO;
            orderDao.updateById(order);
        }catch (Exception e){
            throw new MenuHubException(MenuHubException.ErrorType.INSERT_ERROR,"修改订单评价信息失败");
        }
    }

    //根据时间范围获取订单总额
    @Override
    public Float getPriceByTime(int dayNum) {
        return orderDao.getPriceByTime(dayNum);
    }

    //根据时间范围获取订单数量
    @Override
    public Integer getOrderNumByTime(int dayNum) {
        return orderDao.getOrderNumByTime(dayNum);
    }
}
